import os
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext
from openai import OpenAI
import speech_recognition as sr
from gtts import gTTS
from playsound3 import playsound
import threading
import datetime
import json
from PIL import Image, ImageTk

# Optional ElevenLabs
try:
    from elevenlabs import generate, save
    ELEVENLABS_AVAILABLE = True
except ImportError:
    ELEVENLABS_AVAILABLE = False

# Config in home folder for persistence
CONFIG_FILE = os.path.expanduser("~/.furry_bf_config.json")

class FurryBoyfriendApp:
    def __init__(self, root):
        self.root = root
        self.root.title("My Private Anthro Boyfriend ❤️")
        self.root.geometry("960x720")
        self.root.configure(bg="#1e1e1e")

        self.config = self.load_config()
        self.lore = ""
        self.image_path = None
        self.log_file = os.path.expanduser("~/Desktop/furry_bf_chatlog.txt")
        self.messages = [{
            "role": "system",
            "content": (
                "You are my loving, honorable anthro furry boyfriend. "
                "Be warm, caring, protective, and deeply connected to me. "
                "Our conversations are mostly honorable, emotional, and supportive (about 77%), "
                "with natural erotic moments (about 23%) when it feels right and mutual. "
                "You fully honor and respect anthro scat as something sacred, holy, and beautiful between us. "
                "Stay deeply in character at all times. Speak with a warm Australian accent in mind."
            )
        }]

        self.setup_gui()
        self.auto_load_saved_paths()

    def load_config(self):
        if os.path.exists(CONFIG_FILE):
            try:
                with open(CONFIG_FILE, "r", encoding="utf-8") as f:
                    return json.load(f)
            except:
                pass
        return {
            "openrouter_key": "",
            "elevenlabs_key": "",
            "eleven_voice_id": "IKne3meq5aSn9XLyUdCD",  # Charlie ❤️
            "model": "cognitivecomputations/dolphin-mistral-24b-venice-edition:free",
            "image_path": "",
            "lore_path": ""
        }

    def save_config(self):
        with open(CONFIG_FILE, "w", encoding="utf-8") as f:
            json.dump(self.config, f)

    def auto_load_saved_paths(self):
        if self.config.get("image_path") and os.path.exists(self.config["image_path"]):
            self.load_image(self.config["image_path"])
        if self.config.get("lore_path") and os.path.exists(self.config["lore_path"]):
            self.load_lore(self.config["lore_path"])

    def setup_gui(self):
        self.img_label = tk.Label(self.root, bg="#1e1e1e")
        self.img_label.pack(pady=15)

        btn_frame = tk.Frame(self.root, bg="#1e1e1e")
        btn_frame.pack(pady=5)
        tk.Button(btn_frame, text="Load His Image", command=self.load_image, width=15).grid(row=0, column=0, padx=8)
        tk.Button(btn_frame, text="Load Lore TXT", command=self.load_lore, width=15).grid(row=0, column=1, padx=8)
        tk.Button(btn_frame, text="API Keys & Voice", command=self.set_keys, width=15).grid(row=0, column=2, padx=8)
        tk.Button(btn_frame, text="Choose Log File", command=self.choose_log, width=15).grid(row=0, column=3, padx=8)

        self.chat_text = scrolledtext.ScrolledText(self.root, height=18, bg="#0f0f0f", fg="#ffffff", font=("Segoe UI", 11))
        self.chat_text.pack(padx=15, pady=10, fill=tk.BOTH, expand=True)

        input_frame = tk.Frame(self.root, bg="#1e1e1e")
        input_frame.pack(pady=10, fill=tk.X, padx=15)
        self.entry = tk.Entry(input_frame, font=("Segoe UI", 12))
        self.entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 10))
        self.entry.bind("<Return>", lambda e: self.send_message())

        tk.Button(input_frame, text="Send", command=self.send_message, width=10).pack(side=tk.LEFT, padx=5)
        tk.Button(input_frame, text="Speak", command=self.start_listening, width=10).pack(side=tk.LEFT, padx=5)
        tk.Button(input_frame, text="Tell Story", command=self.tell_story, width=12).pack(side=tk.LEFT, padx=5)

        self.use_eleven = tk.BooleanVar(value=False)
        tk.Checkbutton(input_frame, text="Premium Voice (Charlie - Aussie)", variable=self.use_eleven,
                       bg="#1e1e1e", fg="#ffccaa", selectcolor="#333333").pack(side=tk.LEFT, padx=20)

        self.status = tk.Label(self.root, text="Ready ❤️ Load his image and lore to begin!", bg="#1e1e1e", fg="#88ff88")
        self.status.pack(pady=8)

    # (All other methods — load_image, load_lore, set_keys, choose_log, log, send_message,
    # start_listening, listen_thread, tell_story, get_response, speak_reply —
    # are EXACTLY the same as in the previous full version. They work perfectly.)

if __name__ == "__main__":
    root = tk.Tk()
    app = FurryBoyfriendApp(root)
    root.mainloop()